package seismosurfer.gui.charts;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.help.CSH;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;

import seismosurfer.data.constants.QueryNames;
import seismosurfer.data.constants.UpdateConstants;
import seismosurfer.gui.GUIConstants;
import seismosurfer.http.HttpGateway;
import aw.gui.chart.Chart2D;
import aw.gui.chart.ITrace2D;
import aw.gui.chart.Trace2DSorted;

import com.bbn.openmap.MapHandler;
import com.bbn.openmap.gui.AbstractOpenMapMenu;
import com.bbn.openmap.util.SwingWorker;

/**
 * This menu holds the menu items related to 
 * charting functionality.
 *
 */
public class ChartsMenu extends AbstractOpenMapMenu implements GUIConstants,
        UpdateConstants, QueryNames {
    
    private static final long serialVersionUID = -6011306997432981552L;

    private String defaultText = "Charts";

    private int defaultMnemonic = 'C';

    protected ChartsPanel panel;

    private ActionListener cdListener;

    private ActionListener sdListener;

    public ChartsMenu() {

        super();
        setText(defaultText);
        setMnemonic(defaultMnemonic);

        CSH.setHelpIDString(this, "chartsMenu");

        cdListener = new ClientDataListener();
        sdListener = new ServerDataListener();

        JMenuItem clientSubMenu = new JMenu("Client Data");
        clientSubMenu.setMnemonic(KeyEvent.VK_C);
        this.add(clientSubMenu);

        JMenuItem quakeMenuItem = new JMenuItem(QUAKE_LAYER, KeyEvent.VK_Q);
        clientSubMenu.add(quakeMenuItem);
        quakeMenuItem.addActionListener(cdListener);
        quakeMenuItem.setActionCommand(QUAKE_LAYER);

        JMenuItem macroMenuItem = new JMenuItem(MACRO_LAYER, KeyEvent.VK_M);
        clientSubMenu.add(macroMenuItem);
        macroMenuItem.addActionListener(cdListener);
        macroMenuItem.setActionCommand(MACRO_LAYER);

        JMenu serverSubMenu = new JMenu("Server Data");
        serverSubMenu.setMnemonic(KeyEvent.VK_S);
        this.add(serverSubMenu);

        JMenuItem magMenuItem = new JMenuItem(GI_NOA_SOURCE_NAME, KeyEvent.VK_G);
        serverSubMenu.add(magMenuItem);
        magMenuItem.addActionListener(sdListener);
        magMenuItem.setActionCommand(GI_NOA_SOURCE_NAME);

        JMenuItem depthMenuItem = new JMenuItem(NEIC_SOURCE_NAME, KeyEvent.VK_N);
        serverSubMenu.add(depthMenuItem);
        depthMenuItem.addActionListener(sdListener);
        depthMenuItem.setActionCommand(NEIC_SOURCE_NAME);

        panel = new ChartsPanel();
    }

    public void findAndInit(Object someObj) {
        super.findAndInit(someObj);

        if (someObj instanceof MapHandler) {
            ((MapHandler) someObj).add(panel);
        }
    }

    public void findAndUndo(Object someObj) {
        super.findAndUndo(someObj);

        if (someObj instanceof MapHandler) {
            ((MapHandler) someObj).remove(panel);
        }
    }

    class ClientDataListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            String layerName = e.getActionCommand();
            panel.showChartDialog(layerName);
        }
    }

    class ServerDataListener implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            String source = e.getActionCommand();

            getFrequencies(null, source);

        }
    }

    private Map freq = null;
    
    /**
     * Gets the value/frequency pairs of magnitude
     * data of a data source. The retrieved data
     * are filtered by the MAG_FREQ query.
     * 
     * @param queryName not used
     * @param source the name of the data source
     */
    public void getFrequencies(final String queryName, final String source) {

        final SwingWorker worker = new SwingWorker() {

            public Object construct() {

                freq = HttpGateway.getFrequencies(MAG_FREQ, source);

                return null;
            }

            // Runs on the event-dispatching thread.
            public void finished() {
                Chart2D chart = makeChart();
                showChartFrame(chart);
            }
        };
        worker.start();

    }
    
    /**
     * Shows the given chart panel on a JFrame.
     * 
     * @param chart the Chart2D panel
     */
    protected void showChartFrame(Chart2D chart) {
        JFrame frame = new JFrame("2D Chart for " + "Magnitude frequencies.");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        frame.getContentPane().add(chart, BorderLayout.CENTER);

        frame.setSize(400, 400);

        frame.setLocationRelativeTo(null);

        frame.setVisible(true);
    }
    
    /**
     * Creates a panel that contains a chart
     * with the value/frequency pairs of
     * magnitude data.
     * 
     * @return a Chart2D panel
     */
    protected Chart2D makeChart() {

        Chart2D chart = new Chart2D();
        ITrace2D trace = new Trace2DSorted();

        trace.setColor(Color.RED);

        String legend = "X: Magnitudes, Y: Number of Magnitudes";

        trace.setLabel(legend);
        trace.setName(legend);

        chart.addTrace(trace);

        Set mags = freq.keySet();
        Collection frequencies = freq.values();

        Iterator magIter = mags.iterator();
        Iterator freqIter = frequencies.iterator();

        int size = mags.size();

        for (int i = 0; i < size; i++) {
            double mag = ((Double) magIter.next()).doubleValue();
            double count = ((Integer) freqIter.next()).doubleValue();
            trace.addPoint(mag, count);
        }

        return chart;
    }

}
